﻿using System.Diagnostics;
using System.Reflection;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace TSharp.Core.Aop.Handler
{
    /// <summary>
    /// 异常的处理类
    /// </summary>
    public class LogHandler : ICallHandler
    {
        private int m_EventId = -1;
        private int m_Priority = 5;
        private TraceEventType m_TraceEventType = TraceEventType.Information;

        /// <summary>
        /// Initializes a new instance of the <see cref="LogHandler"/> class.
        /// </summary>
        /// <param name="messageTemplate">The message template.</param>
        /// <param name="categoryName">Name of the policy.</param>
        /// <param name="order">The order.</param>
        public LogHandler(string messageTemplate, string categoryName, int order)
        {
            MessageTemplate = messageTemplate;
            CategoryName = categoryName;
            Order = order;
        }

        /// <summary>
        /// 错误消息模板
        /// </summary>
        public string MessageTemplate { get; set; }

        /// <summary>
        /// 日志类别名称
        /// </summary>
        public string CategoryName { get; set; }

        /// <summary>
        /// 事件号
        /// </summary>
        public int EventId
        {
            get { return m_EventId; }
            set { m_EventId = value; }
        }

        /// <summary>
        /// Trace类型
        /// </summary>
        public TraceEventType TraceEventType
        {
            get { return m_TraceEventType; }
            set { m_TraceEventType = value; }
        }

        /// <summary>
        /// 优先级
        /// </summary>
        public int Priority
        {
            get { return m_Priority; }
            set { m_Priority = value; }
        }

        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }

        #region ICallHandler Members

        /// <summary>
        /// Order in which the handler will be executed
        /// </summary>
        /// <value></value>
        public int Order { get; set; }

        /// <summary>
        /// Implement this method to execute your handler processing.
        /// </summary>
        /// <param name="input">Inputs to the current call to the target.</param>
        /// <param name="getNext">Delegate to execute to get the next delegate in the handler
        /// chain.</param>
        /// <returns>Return value from the target.</returns>
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            PropertyInfo pro = input.Target.GetType().GetProperty("LogMessage");
            if (pro != null)
            {
                IMethodReturn result = getNext()(input, getNext);
                var log = new LogEntry {EventId = EventId};
                if (string.IsNullOrEmpty(MessageTemplate))
                    log.Message = pro.GetValue(input.Target, null) as string;
                else
                    log.Message = MessageTemplate;
                log.Categories.Add(CategoryName);
                log.Severity = TraceEventType;
                log.Priority = Priority;
                log.Title = !string.IsNullOrEmpty(Title) ? Title : log.Message;
                Logger.Write(log);
                return result;
            }
            else
            {
                return getNext()(input, getNext);
            }
        }

        #endregion
    }
}